<?php
declare (strict_types=1);

namespace app\user\logic\teacher;

use app\common\exception\LogicException;
use app\common\logic\category\Category;
use app\course\logic\base\Course;
use app\course\logic\classes\ClassesLink;
use app\school\logic\school\School;
use app\user\event\subscribes\teacher\Teacher as TeacherSubscribe;
use app\user\logic\user\{Account, Follow, Visitor};
use app\user\model\teacher\Teacher as TeacherModel;
use app\user\model\teacher\TeacherLevel;
use ArrayObject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Event;
use think\facade\Request;
use think\Model;

class Teacher extends TeacherModel
{
    /**
     * 检测账号状态
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-17
     */
    public function checkStatus(Teacher $teacher): void
    {
        if ($teacher->status === 0) throw new LogicException('账号已被禁止登录', '账号被禁用');
    }

    public function isTeacher($user_id = 0, $teacher_id = false)
    {
        $user_id = $user_id ?: request()->mid;

        $teacher = $this->where('user_id', $user_id)->where('status', 1)->findOrEmpty();

        return $teacher->isEmpty() ? 0 : ($teacher_id ? $teacher->id : 1);
    }

    /**
     * 判断是否是班主任
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-03-15
     *
     * @param integer $user_id [description]
     * @return boolean          [description]
     */
    public function isHeadmaster($user_id = 0)
    {
        $user_id    = $user_id ?: request()->mid;
        $teacher_id = $this->isTeacher($user_id, true);

        $is_headmaster = app(Course::class)
            ->where('ext_data', '<>', '')
            ->whereRaw('ext_data->"$.headmaster" = ' . $teacher_id)
            // ->buildSql();
            ->findOrEmpty();

        return $is_headmaster->isEmpty() ? 0 : 1;
    }

    /**
     * 讲师列表
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-13
     *
     * @throws DbException
     */
    public function getTeacherList($map)
    {
        $field = '__TABLE__.id,level_id,user_id';
        return $this->withJoin(['teacher_name' => ['nick_name' => 'title']])->where($map)->with(['avatar', 'icon_url'])->field($field)
            ->where('__TABLE__.status', 1)->whereNull('__TABLE__.delete_time')->order(['best_sort' => 'asc', 'update_time' => 'DESC'])
            // ->buildSql();
            ->paginate($this->getListRows())->append(['level_text', 'signature'])->each(function ($i) {
                // $i->level_text = $i->level_text ? : '普通讲师';
                $i->avatar_url = $i->avatar ? $i->avatar->fileurl : '';
            })->hidden(['avatar', 'teacher_name']);
    }

    /**
     * 讲师基础信息
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-03-15
     *
     * @param  [type] $id [description]
     * @return Teacher|array|Model [type]     [description]
     */
    public function getBasicInfo($id)
    {
        $field = 'id,level_id,user_id,mhm_id,info';
        // if (!in_array(request()->device_type, ['ios', 'android'])) $field .= ",info";
        // 讲师基础信息
        $info = $this->with(['avatar', 'school_name', 'icon_url', 'signature'])->field($field)->findOrFail($id)->hidden(['avatar'])->append(['teacher_name', 'level_text']);
        // ->with(['avatar', 'school_name' => function($query) {
        //     $query->where('id', '<>', 1);
        // }])

        // 讲师头像
        // $info->level_text = $info->level_text ? : '普通讲师';
        $info->avatar_url = $info->avatar ? $info->avatar->fileurl : '';
        //
        $userId = $info->getAttr('user_id');
        // 当前用户是否关注
        $info->is_follow = app(Follow::class)->isFollow($userId);
        $info->followed  = $info->is_follow;
        // 添加访客
        if (request()->mid && $userId != request()->mid) {
            app(Visitor::class)->addVisitor($userId);
        }
        // 机构独立域名
        $info->mhm_sdn = app(School::class)->getSdn($info->mhm_id);
        // 简介链接和文本格式
        $info->info_url  = str_replace('basic', 'info', Request::domain() . Request::baseUrl());
        $info->info_text = $info->info;
        // 讲师介绍
        if (in_array(request()->device_type, ['ios', 'android'])) $info->info = str_replace('basic', 'info', Request::domain() . Request::baseUrl());
        // 访客及关注粉丝
        $info->following_num      = app(Follow::class)->getFollowNum($userId);
        $info->fans_num           = app(Follow::class)->getFollowerNum($userId);
        $info->recent_visitor_num = app(Visitor::class)->recentVisitorsNum($userId);
        if ('pc' == request()->device_type) {
            $info->hot_course = app(Course::class)->teacherHotCourse($id, 6);
            // $info->recent_visitors = app(Visitor::class)->recentVisitors($info->user_id, false);
        } else if(in_array(request()->device_type, ['ios', 'android'])) {
            $info->follow          = app(Follow::class)->getFollowNum($info->user_id);
            $info->follower        = app(Follow::class)->getFollowerNum($info->user_id);
            $info->recent_visitors = app(Visitor::class)->recentVisitorsNum($info->user_id);
        }
        // 身份
        $info->identity = 2;

        return $info;
    }

    /**
     * 讲师简介
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-03-15
     *
     * @param  [type] $id [description]
     * @return mixed [type]     [description]
     */
    public function getInfo($id)
    {
        return $this->where('id', $id)->value('info');
    }

    // 讲师主页课程

    /**
     * @throws DbException
     */
    public function getCourse($id, $param)
    {
        // 验证数据
        $this->getValidate()->scene('course')->failException()->check($param);

        $field = 'id,title,course_type,cover,price,vip_price,sale_count,sale_count_market';

        if ($param['course_type']) {
            // 课程分类
            $course = app(Course::class)->getTeacherCourseByCourseType($param['course_type'], $id, $field);
        } else {
            $map = [
                [
                    ['teacher_id', '=', $id],
                    ['status', '=', 1],
                    ['listing_time', '<', time()],
                    ['solo', '=', 1],
                ],
                [
                    ['id', 'IN', app(ClassesLink::class)->getClassesIdsByCourseIds($this->getTeacherCourseIds($id))],
                    ['status', '=', 1],
                    ['listing_time', '<', time()],
                    ['solo', '=', 1],
                ]
            ];

            // 推荐课程
            $course = app(Course::class)
                ->whereOr($map)
                ->field($field)
                ->with(['cover_url'])
                ->order(['best_sort' => 'DESC', 'id'])
                // ->buildSql()
                ->paginate($this->getListRows())
                ->append(['course_type_text', 'user_price']);
        }

        return $course;
    }

    public function getTeacherCourseIds($teacher_id)
    {
        return app(Course::class)->where('teacher_id', $teacher_id)->column('id');
    }

    /**
     * 讲师认证页面渲染
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-06
     */
    public function authFetch()
    {
        $mid         = static::$mid;
        $mhm_id      = request()->user->mhm_id;
        $status_text = $this::getStatusText();
        // 检查认证状态
        $field     = 'fullcategorypath,category,mhm_id,IDcard,IDcard_positive,IDcard_side,certification,status';
        $auth_info = $this
            ->where('user_id', $mid)
            ->with([
                'school_name',
                'IDcard_positive_url',
                'IDcard_side_url',
                'certification_url',
            ])
            ->field($field)
            ->findOrEmpty();

        if ($auth_info->isEmpty()) {
            $return['auth_status']      = 4; //未认证
            $return['auth_status_text'] = '未认证';
            $return['auth_info']        = new ArrayObject();
        } else if ($auth_info->delete_time) {
            $return['auth_status']      = 5;
            $return['auth_status_text'] = '已注销';
            $return['auth_info']        = $auth_info;
        } else {
            $return['auth_status']        = $auth_info->status;
            $return['auth_status_text']   = $status_text[$auth_info->status];
            $auth_info->selected_category = app(Category::class)->getCateLastText($auth_info->fullcategorypath);
            $return['auth_info']          = $auth_info;
        }

        // 机构筛选
        // $return['school'] = app(School::class)->getSelectList(); // 机构
        // pc\h5端数据
        // if (in_array(request()->device_type, ['pc', 'h5', 'miniprogram'])) {
        $return['category'] = app(Category::class)->getTree(0, 'id,title,sort', 1, $mhm_id); // 讲师分类
        // }

        return $return;
    }

    /**
     * 讲师认证提交信息
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-06
     */
    public function authSubmit($param)
    {
        // 验证数据
        $this->getValidate()->scene('auth')->failException()->check($param);

        $param = app(Category::class)->parseFullCateParam($param);

        // 检查重复或重新审核
        // 是否讲师只能一个机构，
        $mid             = static::$mid;
        $exist           = $this->where('user_id', $mid)->findOrEmpty();
        $mhm_id          = app(Account::class)->where('id', $mid)->value('mhm_id');
        $param['mhm_id'] = $mhm_id ?: 1;

        if ($exist->isEmpty()) {
            // 账号已认证
            $exist = $this->where('IDcard', $param['IDcard'])->findOrEmpty();

            if (!$exist->isEmpty()) throw new LogicException('此身份证已认证过讲师');
            // 分类确认
            $param['user_id'] = $mid;
            $param['from']    = request()->device_type;

            // 提交认证
            $success = $this::create($param);

            if ($success->isEmpty()) throw new LogicException("提交认证失败");
            // 日志
            app(TeacherLog::class)->writeLog(intval($param['mhm_id']), '提交审核', $mid);

            // 提交了审核
            Event::subscribe(TeacherSubscribe::class);
            Event::trigger('TeacherAuthSubmit', $success);
            return $success;
        } else {
            // 检查状态     0:禁用 1:正常  2:待认证 3:认证被驳回
            if (in_array($exist->status, [0, 1, 2])) throw new LogicException("你已认证过讲师，请勿重复认证");
            // 身份证已被其他账号认证
            $used = $this->where('IDcard', $param['IDcard'])->where('user_id', '<>', $mid)->findOrEmpty();
            if (!$used->isEmpty()) throw new LogicException('此身份证已认证过其他讲师，请核实身份信息');
            // 重新认证
            $param['from']   = request()->device_type;
            $param['status'] = 2;
            // 提交认证
            $success = $exist->save($param);

            if (!$success) throw new LogicException('提交认证失败');
            // 日志
            app(TeacherLog::class)->writeLog(intval($param['mhm_id']), '重新提交审核', $mid);
            // 提交了审核
            Event::subscribe(TeacherSubscribe::class);
            Event::trigger('TeacherAuthSubmit', $exist);
            return $exist;
        }
    }

    // 注销账号 - 采用假删除，且不能用模型的假删除
    public function removeAccount()
    {
        # code...
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function getRecommend()
    {
        $limit = request()->device_type == 'pc' ? 10 : 5;
        $field = 'id,user_id,level_id';

        return $this->field($field)->where('mhm_id', '=', request()->mhm_id)->scope(['status', 'undelete'])->with(['user.avatarUrl', 'level_text', 'icon_url'])->order(['best_sort' => 'ASC', 'update_time' => 'DESC'])->limit($limit)->select()->bindAttr('user', ['avatar_url', 'title' => 'nick_name'])->hidden(['user']);
    }

    // 获取课程讲师信息

    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     */
    public function getCourseTeacher($course)
    {
        // 讲师IDS
        if ($course->course_type == 4) {
            $course = app(ClassesLink::class)->getCourseMenu($course->id)->toArray();
            $tids   = array_column($course, 'teacher_id');
        } else {
            $tids = (string)$course->teacher_id;
        }

        $data = $this->field('id,user_id,level_id')->where('id', 'IN', $tids)->with([
            'user.avatarUrl',
            'level_text',
            'teacherName',
            'signature',
            'icon_url'
        ])->select()->bindAttr(
            'user',
            ['avatar_url', 'title' => 'nick_name']
        )->hidden(['user']);

        return $data->isEmpty() ? [] : $data;
    }

    public function getTeacherUserId($id)
    {
        return $this->where('id', $id)->value('user_id') ?: 0;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     */
    public function getTeacherAvatar($id)
    {
        $teacher = $this->findOrEmpty($id);
        $user    = app(Account::class)->getUserInfo($teacher->user_id);
        return $user->avatar_url;
    }

    public function getTeacherName($id)
    {
        $teacher = $this->with(['teacher_name'])->findOrEmpty($id);
        return $teacher->title;
    }

    public function isTeacherCourse($course_id, $teacher_id = 0)
    {
        $data = app(Course::class)
            ->where('teacher_id', $teacher_id)
            ->where('id', $course_id)
            ->findOrEmpty();

        return $data->isEmpty() ? 0 : 1;
    }

    /**
     * 获取讲师等级列表信息
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2022-09-30
     */
    public function getSelectLevel($map = [])
    {
        try {
            return app(TeacherLevel::class)->where($map)->field('id,title')->order('id')->select();
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            return [];
        }
    }
}
